package KylinComponents

import (
	"errors"
	"fmt"
	"github.com/gorilla/websocket"
)

type WSConnection struct {
	AllowSend bool
	ClientId  int
	ClientIp  string
	Conn      *websocket.Conn
	InCh      chan []byte
	OutCh     chan []byte
	ExitCh    chan bool
	isClosed  bool
}

/*
 * 创建WebSocket连接
 */
func NewWSConnection(conn *websocket.Conn) (*WSConnection, error) {
	ws := &WSConnection{
		AllowSend: false,
		Conn:      conn,
		InCh:      make(chan []byte, 3000),
		OutCh:     make(chan []byte, 3000),
		ExitCh:    make(chan bool, 1),
	}
	return ws, nil
}

/*
 * 关闭连接
 */
func (conn *WSConnection) Close() {
	if conn.isClosed {
		return
	}
	conn.isClosed = true
	err := conn.Conn.Close()
	if err != nil {
		fmt.Println(err)
	}
	close(conn.InCh)
	close(conn.OutCh)
	close(conn.ExitCh)
	return
}

/*
 * 循环读取
 */
func (conn *WSConnection) reading() {
	defer conn.Close()
	for {
		a, data, err := conn.Conn.ReadMessage()
		fmt.Print(string(a), string(data), err)
		if err != nil {
			conn.ExitCh <- true
			conn.isClosed = true
			return
		}
		conn.InCh <- data
	}
}

/*
 * 循环写
 */
func (conn *WSConnection) writing() {
	for {
		select {
		case data := <-conn.OutCh:
			if err := conn.Conn.WriteMessage(websocket.TextMessage, data); err != nil {
				conn.ExitCh <- true
				return
			}
		case <-conn.ExitCh:
			return
		}
	}
}

/*
 * 启动
 */
func (conn *WSConnection) Start() {
	go conn.reading()
	go conn.writing()
}

func (conn *WSConnection) ReadMessage() ([]byte, error) {
	if conn.isClosed {
		return nil, errors.New("connection close")
	}
	data := <-conn.InCh
	return data, nil
}

func (conn *WSConnection) WriteMessage(data []byte) error {
	if conn.isClosed {
		return errors.New("connection close")
	}
	conn.OutCh <- data
	return nil
}

//————————————————
//版权声明：本文为CSDN博主「中二的灰太狼」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
//原文链接：https://blog.csdn.net/weixin_50134791/article/details/120169093  对原文内容进行修改
